package icedot.app.android.nativeso;

import android.util.Log;
import android.widget.Toast;

import org.json.JSONObject;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import icedot.app.android.nativeso.okhttp.ProgressHelper;
import icedot.app.android.nativeso.okhttp.ProgressListener;
import icedot.app.android.nativeso.okhttp.UIProgressListener;
import icedot.library.common.base.Logger;
import icedot.library.common.utils.CommonDef;
import icedot.library.common.utils.Md5;
import okhttp3.Callback;
import okhttp3.Headers;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * Created by IceDot on 2016/3/8.
 */
public class NetworkManager implements NativeCallback
{
    private NativeClient _client;
    private NativeHandler _handler;
    private Map<String, NetworkNotify> _notifyList = new ConcurrentHashMap<>();
    private Map<String, List<NetworkNotify>> _fileList = new ConcurrentHashMap<>();

    public NetworkManager()
    {
        _client = new NativeClient();
        _handler = new NativeHandler(this);
        _client.setHandler(_handler);
    }

    public void initLongConnect(String ip, int port, String logPath)
    {
        if (CommonDef.s_debug)
        {
            _client.init(ip, port, logPath, 0);
        }
        else
        {
            _client.init(ip, port, logPath, 3);
        }
        //_client.test();
    }

    public void test(NetworkNotify notify)
    {
        byte[] temp = _client.test();
        notify.onSuccess(0, temp);
    }

    public static String getFlags()
    {
        int randomNum = (int) (Math.random() * 1000);
        return String.valueOf(Calendar.getInstance().getTimeInMillis()) + randomNum;
    }

    public void httpPost(String url, String content, NetworkNotify notify)
    {
        String flag = getFlags();
        _notifyList.put(flag, notify);
        _client.httpPost(url, content, flag);
        if (CommonDef.s_debug)
        {
            Logger.showDebugMsg("httpPost flag=" + flag + " send " + url);
        }
    }

    public void httpGet(final String url, final String content, final NetworkNotify notify)
    {
        String flag = getFlags();
        _notifyList.put(flag, notify);
        _client.httpGet(url, content, flag);
        if (CommonDef.s_debug)
        {
            Logger.showDebugMsg("httpGet url=" + url + " flag=" + flag + " send " + url);
        }
    }

    public void httpGetFile(final String url, final String fileName, final NetworkNotify notify)
    {
        String flag = Md5.string2MD5(url);
        if (_fileList.containsKey(flag))
        {
            _fileList.get(flag).add(notify);
        } else
        {
            List<NetworkNotify> list = new ArrayList<>();
            list.add(notify);
            _fileList.put(flag, list);
            _client.httpGetFile(url, fileName, flag, false);
        }

        if (CommonDef.s_debug)
        {
            Logger.showDebugMsg("httpGetFile flag=" + flag + " send " + url);
        }
    }

    public void httpUploadFile(final String url, final String fileName, final JSONObject content, final NetworkNotify notify)
    {
        String flag = getFlags();
        _notifyList.put(flag, notify);
        JSONObject jsonObj = new JSONObject();
        try
        {
            jsonObj.put("inputName", "userfile");
            jsonObj.put("fileName", fileName);
            if (content != null)
            {
                jsonObj.put("content", content);
            }
            _client.httpUploadFile(url, jsonObj.toString(), flag, false);
        }
        catch (Exception e)
        {
            Logger.errorMsg(e.getMessage());
        }

        if (CommonDef.s_debug)
        {
            Logger.showDebugMsg("httpUploadFile flag=" + flag + " send " + url);
        }
    }

    /**
     * 有下载进度通知
     *
     * @param url
     * @param fileName
     * @param notify
     */
    public void httpDownloadFile(final String url, final String fileName, final NetworkNotify notify)
    {
        String flag = Md5.string2MD5(url);
        if (_fileList.containsKey(flag))
        {
            _fileList.get(flag).add(notify);
        } else
        {
            List<NetworkNotify> list = new ArrayList<>();
            list.add(notify);
            _fileList.put(flag, list);
            _client.httpGetFile(url, fileName, flag, true);
        }

        if (CommonDef.s_debug)
        {
            Logger.showDebugMsg("httpDownloadFile flag=" + flag + " send " + url);
        }
    }

    @Override
    public void recvCallback(String flag, int type, byte[] content)
    {
        if (_notifyList.containsKey(flag))
        {
            NetworkNotify info = _notifyList.get(flag);
            if (info == null)
            {
                Logger.showDebugMsg(Logger.s_error, "Exception", "NetworkNotify not find");
                return;
            }
            notify(info,flag,type,content);
            _notifyList.remove(flag);
            Logger.showDebugMsg("remove flag " + flag);
        }
        else if(_fileList.containsKey(flag))
        {
            List<NetworkNotify> list = _fileList.get(flag);
            for(NetworkNotify item:list)
            {
                notify(item,flag,type,content);
            }
            _fileList.remove(flag);
            Logger.showDebugMsg("remove flag " + flag);
        }
        else
        {
            Logger.errorMsg(flag + " not find");
        }

    }

    private void notify(NetworkNotify notify, String flag, int type, byte[] content)
    {
        try
        {
            if (type == NativeClient.s_httpSuccess || type == NativeClient.s_httpProcess)
            {
                notify.onSuccess(type, content);
            } else if (type == NativeClient.s_httpError)
            {
                String ret = new String(content, "UTF-8");
                if (CommonDef.s_debug)
                {
                    notify.onNoNetwork(type, ret.toString());
                } else
                {
                    ret = "获取数据异常,请重试...";
                    notify.onNoNetwork(type, ret.toString());
                }
                Logger.errorMsg("flag=" + flag + " type=" + type + " POST<--" + ret.toString());
            } else if (type == NativeClient.s_noNetwork)
            {
                String ret = new String(content, "UTF-8");
                notify.onNoNetwork(type, ret.toString());
                if (CommonDef.s_debug)
                {
                    Logger.errorMsg("flag=" + flag + " type=" + type + " POST<--" + ret.toString());
                }
            }
        }
        catch (Exception e)
        {
            Logger.showDebugMsg(Logger.s_error, "Exception", e.getMessage());
        }
    }
}
